﻿using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using System.Security;
using System.Reflection;
using System.Web.Security;
using System.Collections.Specialized;
using SWGeneracionE.Models;
using SWGeneracionE.Models.Repositories;

namespace SWGeneracionE.Controllers
{
    [HandleError(ExceptionType = typeof(SecurityException), View = "AuthorizeError")]
    public class BaseController : Controller
    {

        protected UnitOfWork UoW = new UnitOfWork();
        protected const int c_parametro_eventodefault = 1;
        protected const int c_parametro_longitudcodigo = 2;
        protected const int c_iglesia_ningunacodigo = 1;
        protected const int c_iglesia_localcodigo = 2;
        protected const int c_pais_localcodigo = 1;
        
        protected IList<webpages_Menu> BuildMenu()
        {
            IList<webpages_Menu> menuList = new List<webpages_Menu>();
            bool isAutenticated = User.Identity.IsAuthenticated;

            if (isAutenticated)
            {
                try
                {
                    menuList = (List<webpages_Menu>)Session["menuList"];
                }
                catch (Exception ex) { }
            }

            return menuList;
        }

        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
            ViewBag.Menu = BuildMenu();
            ViewBag.Evento = GetValorParametro(c_parametro_eventodefault);
        }

        protected override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            base.OnActionExecuted(filterContext);
            IList<webpages_Menu> menuList = null;
            bool isAutenticated = User.Identity.IsAuthenticated;
            bool authorize = false;
            bool requiresAuthorization = false;
            MemberInfo[] members = null;

            members = this.GetType().GetMember(filterContext.ActionDescriptor.ActionName);
            foreach (MemberInfo item in members)
            {
                if (item is MethodInfo)
                {
                    foreach (Attribute att in item.GetCustomAttributes(false))
                    {
                        if (att is AuthorizeAttribute)
                        {
                            requiresAuthorization = true;
                            break; // TODO: might not be correct. Was : Exit For
                        }
                        if (requiresAuthorization)
                            break; // TODO: might not be correct. Was : Exit For
                    }
                }
            }
            if (!requiresAuthorization)
                return;

            menuList = (List<webpages_Menu>)ViewBag.Menu;
            if ((menuList != null))
            {
                authorize = AccionPermitida(menuList, filterContext.ActionDescriptor.ActionName, 
                                            filterContext.ActionDescriptor.ControllerDescriptor.ControllerName);
            }

            authorize = authorize & isAutenticated;
            if (requiresAuthorization & (!authorize))
            {
                throw new SecurityException();
            }
        }

        protected bool AccionPermitida(IList<webpages_Menu> menuList, string ActionName, string ControllerName)
        {
            bool authorize = false;
            foreach (webpages_Menu mp in menuList)
            {
                if ( (mp.Accion.Equals(ActionName)) && (mp.Controlador.Equals(ControllerName)) )
                {
                    authorize = true;
                    break; // TODO: might not be correct. Was : Exit For
                }
            }

            return authorize;
        }

        protected string RenderPartialViewToString(string viewName, object model)
        {
            if (string.IsNullOrEmpty(viewName))
                viewName = ControllerContext.RouteData.GetRequiredString("action");

            ViewData.Model = model;

            using (StringWriter sw = new StringWriter())
            {
                ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
                ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
                viewResult.View.Render(viewContext, sw);

                return sw.GetStringBuilder().ToString();
            }
        }

        #region "Funciones Generales"
        protected string GetValorParametro(int idParametro)
        {
            string valor = "";
            try
            {
                SWGeneracionE.Models.Parametro parametro = UoW.parametroRepository.FindFirst(p => p.idParametro == idParametro);
                valor = parametro.Valor.Trim();
            }
            catch (Exception ex) { }

            return valor;
        }

        protected void AgregarBitacora(string mensaje, string controlador = null, string accion = null)
        {
            try
            {
                Bitacora bitacora = new Bitacora();
                bitacora.fechaHora = DateTime.Now;
                bitacora.descripcion = mensaje;
                bitacora.usuario = User.Identity.Name;

                if ((controlador != null) && (accion != null))
                {
                    controlador = controlador.Trim();
                    accion = accion.Trim();
                    webpages_Menu menu = UoW.webpages_MenuRepository.FindFirst(m => m.Controlador == controlador && m.Accion == accion);
                    if (menu != null)
                        bitacora.idMenu = menu.IdMenu;
                }

                UoW.bitacoraRepository.Add(bitacora);
                UoW.Save();
            }
            catch (Exception ex) { }
        }

        protected void EnviarCorreo(string destinatario, string asunto, string texto, bool bGuardar)
        {
            try
            {
                Notificacion notificacion = new Notificacion();
                notificacion.asunto = asunto;
                notificacion.destinatario = destinatario;
                notificacion.texto = texto;
                UoW.notificacionRepository.Add(notificacion);
                if (bGuardar)
                    UoW.Save();
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error EnviarCorreo: " + ex.Message + "--" + ex.Source);
            }
        }
        #endregion

        protected override void Dispose(bool disposing)
        {
            UoW.Dispose();
            base.Dispose(disposing);
        }
    }

}